<template>
    <div class="testcaseContainer">
        <!--头部面包屑-->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>测试执行</el-breadcrumb-item>
            <el-breadcrumb-item>测试用例</el-breadcrumb-item>
        </el-breadcrumb>

        <!--查询卡片-->
        <el-card class="box-card ">
            <el-form ref="queryFormRef" :inline="true" :model="queryTestcaseForm" class="queryUserKeywordForm">
                <el-form-item label="用例名" prop="name">
                    <el-input v-model="queryTestcaseForm.name" placeholder="用例名" clearable></el-input>
                </el-form-item>
                <el-form-item label="测试项目" prop="projectName">
                    <el-select v-model="queryTestcaseForm.projectName" filterable placeholder="请选择">
                        <el-option
                                v-for="project in projects"
                                :key="project.id"
                                :label="project.name"
                                :value="project.name">
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="描述" prop="description">
                    <el-input v-model="queryTestcaseForm.description" placeholder="描述" clearable></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" icon="el-icon-search" @click="getTestcaseList()">查询</el-button>
                    <el-button type="info" icon="el-icon-search" @click="resetQueryForm()">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>

        <!--表格-->
        <el-card class="box-card">
            <el-button type="primary" icon="el-icon-circle-plus" @click="newTestCaseDialogVisile = true">
                新增
            </el-button>
            <!--            <el-button @click="showNewTestcaseFormModel">show newTestcaseFormModel</el-button>-->
            <!--            <el-button @click="showEditTestcaseFormModel">show editTestcaseFormModel</el-button>-->
            <el-table
                    :data="testcaseList"
                    border
                    style="width: 100%"
                    :header-cell-style="headerCellstyle"
                    stripe>
                <el-table-column
                        type="index"
                        label="序号"
                        width="60px">
                </el-table-column>
                <el-table-column
                        prop="name"
                        label="用例名"
                        width="180">
                </el-table-column>
                <el-table-column
                        prop="projectName"
                        label="所属项目"
                        width="180">
                </el-table-column>
                <el-table-column
                        prop="description"
                        label="用例功能描述">
                </el-table-column>
                <el-table-column label="参数" width="60">
                    <template slot-scope="scope">
                        <el-button icon="el-icon-edit-outline" circle type="info"
                                   @click="showTestdata(scope.row)"></el-button>
                    </template>

                </el-table-column>
                <el-table-column
                        label="用例操作"
                        width="130">
                    <template slot-scope="scope">
                        <el-button type="primary" icon="el-icon-edit" circle
                                   @click="editTestcase(scope.row.id)"></el-button>
                        <el-button type="danger" icon="el-icon-delete" circle
                                   @click="deleteATestcase(scope.row.id)"></el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>

        <!--分页 暂时先不看-->
        <el-pagination


                :page-sizes="[100, 200, 300, 400]"
                :page-size="100"
                layout="total, sizes, prev, pager, next, jumper"
                :total="400">
        </el-pagination>

        <!--新增用例的对话框和表单-->
        <el-dialog :visible.sync="newTestCaseDialogVisile" title="新增测试用例" @open="getProjects"
                   @close="whenNewTestcaseDialogClose" center fullscreen>
            <el-form :model="newTestCaseVo" ref="newTestcaseDialogRef">
                <el-col>
                    <el-row :gutter="20">
                        <el-col :span="5">
                            <el-form-item label="用例名" prop="name">
                                <el-input v-model="newTestCaseVo.name" placeholder="请输入用例英文名"></el-input>
                            </el-form-item>
                            <el-form-item label="关联项目" prop="projectName">
                                <el-select v-model="newTestCaseVo.projectName" filterable placeholder="请选择">
                                    <el-option
                                            v-for="project in projects"
                                            :key="project.id"
                                            :label="project.name"
                                            :value="project.name">
                                    </el-option>
                                </el-select>
                            </el-form-item>
                            <el-form-item label="用例描述" prop="description">
                                <el-input v-model="newTestCaseVo.description" placeholder="请输入用例描述"
                                          type="textarea" :rows="10"></el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="19">
                            <el-form-item label="用例脚本" prop="code">
                                <el-input v-model="newTestCaseVo.code" type="textarea" :rows="20"></el-input>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-col>


            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="newTestCaseDialogVisile = false">取 消</el-button>
                <el-button type="primary" @click="newTestcase()">确 定</el-button>
            </div>
        </el-dialog>

        <!--编辑用例的对话模框和表单-->
        <el-dialog :visible.sync="editTestCaseDialogVisible" title="编辑测试用例"
                   @close="whenEditTestcaseDialogClose" center fullscreen>
            <el-form :model="editTestCaseVo" ref="editTestcaseDialogRef">
                <el-row :gutter="20">
                    <el-col :span="5">
                        <el-form-item label="用例名" prop="name">
                            <el-input v-model="editTestCaseVo.name" placeholder="请输入用例英文名" disabled></el-input>
                        </el-form-item>
                        <el-form-item label="关联项目" prop="projectName">
                            <el-input v-model="editTestCaseVo.projectName" disabled></el-input>
                        </el-form-item>
                        <el-form-item label="用例描述" prop="description">
                            <el-input v-model="editTestCaseVo.description" placeholder="请输入用例描述"
                                      type="textarea" :rows="10"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="19">
                        <el-form-item label="用例脚本" prop="code">
                            <el-input v-model="editTestCaseVo.code" type="textarea" :rows="20"></el-input>
                        </el-form-item>
                    </el-col>
                </el-row>

            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="editTestCaseDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="updateTestcase()">确 定</el-button>
            </div>
        </el-dialog>

        <!--显示测试数据的对话框-->
        <el-dialog :visible.sync="testdataDialogVisible" title="测试数据列表" center @close="whenTestdataDialogClose"
            width="60%">

            <div class="btnUnderTableContainer">
                <el-button  type="primary" icon="el-icon-plus" @click="addATestdataLine">新增</el-button>
            </div>
            <!--新增1行测试数据按钮-->

            <el-table ref="testdataTableRef" :data="testdata.testdataList" stripe border @expand-change="expandChange" :row-key="getRowKey"
                      :expand-row-keys="expandRowKeys" :header-cell-style="headerCellstyle">

                <!--展开行，嵌套testdataItem表格-->
                <el-table-column type="expand" label="展开">
                    <template slot-scope="scope">
                        <!--新增1行测试数据项按钮-->
                        <el-table  :data="scope.row.childData" stripe :header-cell-style="headerCellstyle" border>
                            <el-table-column type="index" label="序号"></el-table-column>
                            <el-table-column label="参数名">
                                <template scope="scope">
                                    <el-input size="small" v-model="scope.row.parameterName"></el-input>
                                </template>
                            </el-table-column>
                            <el-table-column label="参数值">
                                <template scope="scope">
                                    <el-input size="small" v-model="scope.row.parameterValue"></el-input>
                                </template>
                            </el-table-column>
                            <el-table-column label="操作" width="120px">
                                <template scope="scope">
                                    <el-button  circle type="primary" icon="el-icon-check" @click="saveTestdataItem(scope.row)"></el-button>
                                    <el-button  circle type="danger" icon="el-icon-close" @click="deleteTestdataItem(scope.row)"></el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </template>
                </el-table-column>

                <el-table-column type="index" label="序号">
                </el-table-column>
                <el-table-column label="数据名称">
                    <template scope="scope">
                        <el-input size="small" v-model="scope.row.name"></el-input>
                    </template>
                </el-table-column>
                <el-table-column label="描述" >
                    <template scope="scope">
                        <el-input size="small" v-model="scope.row.description"></el-input>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="160px">
                    <template slot-scope="scope">
                        <el-button  circle type="primary" icon="el-icon-check" @click="saveTestData(scope.row)"></el-button>
                        <el-button circle type="primary" icon="el-icon-plus" @click="addATestdataItem(scope.row)"></el-button>
                        <el-button  circle type="danger" icon="el-icon-close" @click="deleteTestdata(scope.row)"></el-button>
                    </template>
                </el-table-column>

            </el-table>


        </el-dialog>

    </div>
</template>

<script>
    export default {
        name: "Testcase",
        created() {
            this.getTestcaseList();
        },
        data() {
            return {

                queryTestcaseForm: {
                    name: '',
                    projectName: '',
                    description: ''
                },
                testcaseList: [],
                newTestCaseDialogVisile: false,
                newTestCaseVo: {
                    name: '',
                    projectName: '',
                    description: '',
                    code: '*** Settings ***\n' +
                        'Resource    (userKeywordResource)\n' +
                        '\n' +
                        '*** Test Cases ***\n' +
                        'testcaseName\n'
                },
                /*projects容器*/
                projects: [],

                /*编辑测试用例对话框的显示开关*/
                editTestCaseDialogVisible: false,

                /*编辑测试用例VO的容器*/
                editTestCaseVo: {},

                /*控制测试数据diaglog的展示*/
                testdataDialogVisible: false,

                /*测试数据数组*/
                testdata:{testcase:{},testdataList: []},


                /*测试数据表格的展开行数组*/
                expandRowKeys: [],

                headerCellstyle:{'background-color': '#f5f7fa'},


            }
        },
        methods: {

            /*获取测试用例列表*/
            async getTestcaseList() {


                const {data: res} = await this.$http.post('testcase/getVOlist', this.queryTestcaseForm);
                // console.log(res);
                if (res.status !== 200) {
                    return this.$message.error('获取用例列表失败！')
                }
                this.testcaseList = res.data;

            },
            /*点击新增用例*/
            async newTestcase() {
                const {data: res} = await this.$http.post('testcase/newTestcase', this.newTestCaseVo);
                if (res.status === 200) {
                    this.$message.success('新增用例成功');
                    this.getTestcaseList();
                    this.newTestCaseDialogVisile = false;
                } else {
                    this.$message.error('新增用例失败，请核对数据');
                }

            },
            /*点击编辑测试用例*/
            async editTestcase(id) {

                /*从服务器获取最新的testcase数据，根据id*/

                const {data: res} = await this.$http.post('testcase/getTestcaseVObyId?id=' + id);

                if (res.status !== 200) {
                    return this.$message.error('获取测试用例信息失败')
                }
                this.editTestCaseVo = res.data;


                this.editTestCaseDialogVisible = true;
            },
            async updateTestcase() {
                console.log(this.editTestCaseVo.id)
                const {data: res} = await this.$http.post('testcase/updateTestcase', this.editTestCaseVo)
                if (res.status !== 200) {
                    return this.$message.error('保存测试用例失败')
                }
                this.$message.success('保存测试用例成功')
                this.getTestcaseList();
                this.editTestCaseDialogVisible = false;
            },
            /*重置查询表单*/
            resetQueryForm() {
                this.$refs.queryFormRef.resetFields();
            },

            /*获取所有projects*/
            async getProjects() {

                const {data: res} = await this.$http.get('project/getAll')
                if (res.status !== 200) {
                    return this.$message.error('获取projects list失败')
                }
                this.projects = res.data;
            },

            /*当新增用例对话框被关闭时触发*/
            whenNewTestcaseDialogClose() {

                this.$refs.newTestcaseDialogRef.resetFields();
            },

            /*当编辑测试用例对话框被关闭*/
            whenEditTestcaseDialogClose() {
                this.editTestCaseVo = {};
            },

            // showNewTestcaseFormModel(){
            //     this.$message.info(this.newTestCaseVo.code)
            // },
            // showEditTestcaseFormModel(){
            //     this.$message.info(this.editTestCaseVo.name)
            // },

            /*点击删除测试用例时*/
            deleteATestcase(id) {

                /*先弹框提示用户确认*/
                this.$confirm('此操作将删除该测试用例, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(async () => {

                    const {data: res} = await this.$http.get('testcase/deleteOne' + '?id=' + id);

                    if (res.status === 200) {
                        this.$message({
                            type: 'success',
                            message: '删除成功!'
                        });
                        this.getTestcaseList();
                    } else {
                        this.$message.error('删除测试用例失败！')
                    }


                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            },

            /*点击测试数据*/
            async showTestdata(row) {

                /*从后台获取该测试用例的测试数据*/
                const {data: res} = await this.$http.get('testdata/getTestdataList?testcaseId=' + row.id);
                if (res.status !== 200) {
                    return this.$message.error('获取测试数据失败')
                }
                if(res.data !== undefined){
                    this.testdata.testdataList = res.data;
                    this.testdata.testcase = row;
                }

                this.testdataDialogVisible = true;

            },

            /*测试数据行时状态变化时*/
            async expandChange(row, expandedRows) {


                /*如果i === -1 就是折叠当前行，return*/
                let i = expandedRows.indexOf(row);
                if (i === -1) {
                    return;
                }

                /*折叠所有其它行,折叠所有行 再展开当前行*/
                this.expandRowKeys = [];

                /*如果该数据行还没有id,则不应发请求*/
                if(row.id === undefined){
                    return this.$message.error('请先保存测试数据行！')
                }





                /*为折叠行表格挂载childData数据 */
                const {data: res} = await this.$http.get('testdataItem/getTestdataItemListByTestdataId?testdataId=' + row.id);
                this.testdata.testdataList.forEach((item) => {

                    /*找到表格中的这一列，为他设置childData属性*/
                    if (item.id === row.id) {
                        item.childData = res.data;
                    }
                }, this)

                /*等子表格数据加载完成再展开子表格*/
                this.expandRowKeys.push(expandedRows[i].id + '')


            },

            /*获取rowkey*/
            getRowKey(row) {

                return row.id + '';
            },

            /*当测试数据对话框关闭时*/
            whenTestdataDialogClose(){
                /*清空testdata*/
                this.testdata={testcase:{},testdataList: []};
                this.expandRowKeys = []
            },

            /*点击新增数据*/
            addATestdataLine(){

                /*同时只允许新增1行*/
                let lastIndex = this.testdata.testdataList.length-1;


                if(lastIndex !== -1 && this.testdata.testdataList[lastIndex].id === undefined){
                    return this.$message.warning('一次只能新增一套测试数据');
                }


                /*给测试数据表格新增一行数据*/
                this.testdata.testdataList.push({})

                console.log(this.testdata.testdataList)
            },


            /*保存testdataItem*/
            async saveTestdataItem(row){

                /*通过ID判断是新增还是编辑*/
                if(row.id !== undefined){

                    /*保存编辑*/
                    const {data:res} = await this.$http.post('testdataItem/updateTestdataItem',row)
                    if(res.status !== 200){
                        return this.$message.error('保存参数失败！')
                    }
                    this.$message.success('保存参数成功')

                }else{
                    /*新增testdataItem*/
                    /*获取testdataId*/
                    row.testdataId = this.$refs.testdataTableRef.expandRowKeys[0];

                    const {data:res} = await this.$http.post('testdataItem/newTestdataItem',row)
                    if(res.status !== 200){
                        return this.$message.error('新增测试参数失败');
                    }
                    row.id = res.data.id;
                    this.$message.success('新增测试成功')
                }




            },

            /*删除测试数据项*/
            deleteTestdataItem(row){

                this.$confirm('此操作将永久删除该参数, 是否继续?','提示',{
                    confrimButtonText:'确定',
                    cancelButtonText:'取消',
                    type:'warning'
                }).then(async ()=>{

                    /*已保存还是未保存*/
                    if(row.id === undefined){
                        /*将展开行的childData最后一项去除即可*/

                        this.testdata.testdataList.forEach((item)=>{
                            if(item.id+'' === this.$refs.testdataTableRef.expandRowKeys[0]){
                                item.childData.pop();
                            }
                        })
                    }else{
                        /*调用接口删除testdataitem*/
                        const {data:res} = await this.$http.get('testdataItem/deleteOne?id='+row.id);
                        if(res.status != 200){
                            return this.$message.error('删除测试参数失败');
                        }
                        /*刷新childdata*/

                        this.expandRowKeys=[]


                        return this.$message.success('删除测试参数成功')
                    }


                }).catch()

            },

            /*点击新增数据项*/
            addATestdataItem(row){

                let lastIndex = row.childData.length-1;

                if(lastIndex !== -1 && row.childData[lastIndex].id === undefined){
                    return this.$message.warning('一次只能新增一个参数');
                }

                row.childData.push({})
            },

            /*保存testdata*/
            async saveTestData(row){

                /*判断是保存还是新增*/
                if(row.id !== undefined){

                    let param = {};
                    param.testcaseId = this.testdata.testcase.id;
                    param.id = row.id;
                    param.name = row.name;
                    param.description = row.description;

                    const {data:res} = await this.$http.post('testdata/updateTestdata',param);
                    if(res.status !== 200){
                        return this.$message.error('保存测试数据失败');
                    }
                    this.$message.success('保存测试数据成功')
                }else{

                    /*给row加关联的relatedTestcase*/
                    row.testcaseId = this.testdata.testcase.id;

                    const {data:res} = await this.$http.post('testdata/newTestdata',row);

                    if(res.status !== 200){
                        return this.$message.error('新增测试数据失败');
                    }
                    /*如果是新增的，还要给这个row赋1个id*/
                    row.id = res.data.id;
                    this.$message.success('新增测试数据成功')
                }
                console.log(this.testdata)
            },

            /*删除testdata*/
            deleteTestdata(row){
                this.$confirm('此操作将永久删除该测试数据, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then( async () => {

                    /*有id才发起删除*/
                    if(row.id !== undefined){
                        /*调用remote接口删除testdata*/
                        let res = {}
                        try {
                            let result = await this.$http.get('testdata/deleteOne?id='+row.id);
                            res = result.data;
                        }catch (e) {
                            this.$message.error('请求服务器失败，错误信息为：'+e.toString())
                            return;
                        }


                        if(res.status !== 200){
                            return this.$message.error('删除测试数据失败');
                        }
                    }


                    let index = this.testdata.testdataList.indexOf(row);

                    this.testdata.testdataList.splice(index,1)

                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });

                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            }

        }
    }
</script>

<style lang="less" scoped>


    .el-card {
        margin-bottom: 20px;
    }

    .el-table {
        margin-top: 10px;
    }
    .btnUnderTableContainer{
        display: flex;
        justify-content: flex-end;
    }
</style>